package com.punch.common.tools;


import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.punch.common.page.PageInfo;
import com.punch.common.query.QueryInfo;
import com.punch.common.utils.MapUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.function.Function;

/**
 * 多表查询分页工具
 *
 * @author tanchangguo
 * @date 2020/7/14 21:30
 */
@Slf4j
public abstract class BasePage<PK, T> {
    public static <U> PageInfo<U> queryBasePage(QueryInfo queryInfo,
                                                Function<Map<String, Object>, Integer> queryCountFunction,
                                                Function<Map<String, Object>, List<U>> queryDataFunction) {
        return queryBasePage(queryInfo, null, queryCountFunction, queryDataFunction);
    }

    /**
     * 分页查询VO列表
     *
     * @param queryInfo          查询条件
     * @param extractFunction    查询条件解析方法
     * @param queryCountFunction 查询总数方法
     * @param queryDataFunction  查询列表方法
     * @param <U>
     * @return
     */
    public static <U> PageInfo<U> queryBasePage(QueryInfo queryInfo,
                                                Function<QueryInfo, Map<String, Object>> extractFunction,
                                                Function<Map<String, Object>, Integer> queryCountFunction,
                                                Function<Map<String, Object>, List<U>> queryDataFunction) {
        if (queryInfo != null && StringUtils.isBlank(queryInfo.getOrderBySql())) {
            queryInfo.addSort(QueryInfo.DEFAULT_SORT_COLUMN, QueryInfo.DEFAULT_DIRECTION);
        }
        PageInfo<U> pageInfo = null;
        if (queryInfo != null) {
            pageInfo = new PageInfo<>(queryInfo.getCurrPage(), queryInfo.getPageSize());
        } else {
            pageInfo = new PageInfo<>(PageInfo.DEFAULT_PAGE_NO, PageInfo.DEFAULT_PAGE_SIZE);
        }

        Map<String, Object> params = extractFunction == null ? extractParams(queryInfo) : extractFunction.apply(queryInfo);
        List<U> data = null;
        try {
            Integer count = queryCountFunction.apply(params);
            if (count == null) {
                count = 0;
            }
            pageInfo.setTotalCount(count);
            if (count > 0) {
                if (pageInfo.getTotalPage() < queryInfo.getCurrPage()) {
                    queryInfo.setCurrPage(pageInfo.getTotalPage());
                    params.put("offset", queryInfo.getOffset());
                }
                data = queryDataFunction.apply(params);
            }
        } catch (Exception e) {
            log.error("查询分页出错:{}", e.getMessage());
        }

        if (data == null) {
            data = Lists.newArrayList();
        }
        pageInfo.setData(data);
        return pageInfo;
    }


    /**
     * bean -> map
     *
     * @param queryInfo
     * @return
     */
    public static Map<String, Object> extractParams(QueryInfo queryInfo) {
        Map<String, Object> params = Maps.newHashMap();
        if (queryInfo == null) {
            return params;
        }
        MapUtil.populateMap(params, queryInfo);
        if (queryInfo.params().size() > 0) {
            params.putAll(queryInfo.params());
        }
        return params;
    }

}
